import { post } from '@/utils/api-requester';
import { merge } from 'lodash';

import { showErrorMsg, showSuccessMsg } from '@/components/exception/GlobalMessage';
import StorageUtils from '@/utils/StorageUtils';
import { SESSION } from '@/constants/ModelNamespaces';
import StringUtils from '@/utils/StringUtils';
import { LOGIN_URL, LOGOUT_URL } from "@/constants/URLs";
// import { changePropertyName } from '@/utils/ObjectUtil';

//selectors
const getState = state => state[SESSION];

const session = {
    //用于区分不同组件的Reducer、state、effects、actionType等。
    namespace:SESSION,
    //相当于于传统reducer中的initialState.
    state:{
        session: {
            'session_id': '',
            'create_time': 0,
            'display_name': '',
            'authority': ''
        },
    },
    //相当于redux-saga中的saga worker,或者redux-thunk中执行副作用操作的action处理类.
    //每个effect中第一个参数就是action:{type,payload},第二个参数包含redux-saga的put(相当于redux的store.dispatch)和call(类似于js中的function.call,但支持异步).还可以获取到select(相当于redux的store.getState())
    effects:{
        'login':function* ({payload},{ put, call }){
            try {
                const resp = yield call(post, LOGIN_URL, payload);
                /*
                {
                    'error_code': 0,
                    'data': {
                        'session_id': '',
                        'create_time': 12333333,
                        'display_name': 'lily',
                        'authority': 'root'
                    }
                }
                */
                const { error_code, data } = resp.data;
                if(error_code === 0) {
                    const payload = {
                        session: data
                    };
                    yield put({ type: 'saveSession', payload: payload });
                    showSuccessMsg('登陆成功!');
                }else{
                    throw new Error(data);
                }
            } catch (e) {
               yield put({ type: 'saveSession', payload: { error: e }, error:true });
               showErrorMsg(e);//错误消息提示
            }
        },
        *logout({_},{ put, call, select }){
            try{
                let state = yield select(getState);
                let sessionId = StringUtils.isNotBlank(state.session.session_id) ? state.session.session_id : StorageUtils.getSessionId();

                const resp = yield call(post, LOGOUT_URL+'/'+sessionId);
        
                const { error_code, data } = resp.data;
                if (error_code === 0) {
                    yield put({ type: 'removeSession' });
                    showSuccessMsg('注销成功!');
                }else{
                    throw new Error(`${error_code },${data}`);
                }
            }catch(e) {
                yield put({ type: 'removeSession', payload: { error: e }, error:true });
                showErrorMsg(e);//错误消息提示
            }
        }
    },
    //相当于传统redux项目中的reducer.js.传统的需要根据action.type进行switch选择,然后更新store的state.
    //dva里使用每一个reducer的函数名代替action.type
    reducers:{
        //由于dva自动提供loading状态的管理,因此不需要传统的LOGIN_START,LOGIN_FAIL等状态.可以少写很多switch判断.
        saveSession:(state, action)=>{
            //session存入浏览器的sessionStorage.这样项目即使重启,登录状态也可以保持.
            StorageUtils.setSessionItem('session', action.payload.session);
            return merge({}, state, action.payload);
        },
        removeSession(state, {payload}){
            let temp = merge({}, state, payload);
            // if(!payload.error){
                StorageUtils.setSessionItem('session', null);
                temp.session = {};
            // }
            
            return temp;
        },
    }
}
export default session;
